﻿package cocoaas3.starling{

	import flash.events.*;
	import flash.display.*;
	import flash.geom.*;
	import jp.dividual.nativeExtensions.*;

	public class UIScrollView extends UIView {

		// original
		public var contentSize:CGSize;// 外部から指定
		private var _dragging:Boolean = false;// ドラッグ中か？
		public function get dragging():Boolean{
			return _dragging;
		}
		public var decelerationRate:Number = 1.1;

		// custom
		private var _mouseDownPosY:int = 0;// mouseDown した時のマウスの stageY
		private var _posYOnMouseDown:int = 0;// mouseDown した時の自身の y 座標
		private var _prevPosY:Number = 0;
		private var _speed:Number = 0;
		private var _isScrolling:Boolean = false;// スクロール中か？
		private var _hasMaskSet:Boolean = false;// マスクせっとした？
		private var _mouseMoveProcessed:Boolean = false;// 負荷軽減のため、1フレームに1回しかMouseMoveイベントを処理しないように判定するフラグ	
		private var previousMouseStagePoint:Point = new Point();
		private var mouseDown:Boolean = false;// UIScrollView上でマウス押したか？

		public function UIScrollView( frameSize:CGSize ){
			this.frame = new CGRect( 0, 0, frameSize.width, frameSize.height );
			this.addEventListener( Event.ADDED_TO_STAGE, _onAddedToStage );

			this.scrollRect = new Rectangle( 0, 0, frameSize.width, frameSize.height );
			this.cacheAsBitmap = true;
		}


		private function _onAddedToStage( e ):void {
			if( !contentSize ){
				throw new Error( "UIScrollView : ステージに追加する前にcontentSizeを設定してください。" );
			}
			background_mc.width = contentSize.width;
			background_mc.height = contentSize.height;

			this.addEventListener( Event.ENTER_FRAME, _loop );
			this.addEventListener( MouseEvent.MOUSE_DOWN, _onMouseDown );
			stage.addEventListener( MouseEvent.MOUSE_MOVE, _onMouseMove );
			stage.addEventListener( MouseEvent.MOUSE_UP, onStageMouseUp );
		}

		//override protected function atCastRemoved():void {
		//	trace( "UIScrollView atCastRemoved" );
		//	this.removeEventListener( Event.ENTER_FRAME, _loop );
		//	this.removeEventListener( MouseEvent.MOUSE_DOWN, _onMouseDown );
		//	stage.removeEventListener( MouseEvent.MOUSE_UP, myStopDrag );
		//}



		private function _onMouseDown( e:MouseEvent ):void{
			_speed = 0;
			mouseDown = true;
			_mouseDownPosY = e.stageY;
			_posYOnMouseDown = subviewContainer.y;
		}


		private function onStageMouseUp( e:MouseEvent ):void{
			Console.log( "UIScrollView ドラッグを終了しました。" );
			_dragging = false;
			mouseDown = false;
		}

		private function _onMouseMove( e:MouseEvent ):void{
			if( mouseDown ){
				_speed = previousMouseStagePoint.y - e.stageY;
			}

			previousMouseStagePoint.x = e.stageX;
			previousMouseStagePoint.y = e.stageY;

			if( mouseDown == false ){
				return;
			}

			var gap:int = e.stageY - _mouseDownPosY;
			// タッチ後少しでも動いたら、ドラッグ中と判断する
			if( _dragging == false && (gap<0?-gap:gap) > 1 ){// 高速に絶対値を求める
				//Console.log( "UIScrollView ドラッグ開始しました。" );
				_dragging = true;
				subviewContainer.mouseChildren = false;
				_isScrolling = true;
			}

			if( _mouseMoveProcessed ){
				return;
			}

			var bottom:int = getBottom();
			// 領域外へスライドしようとしたときは抵抗を加える
			if( subviewContainer.y > 0 ){
				subviewContainer.y = (_posYOnMouseDown + gap)/2;
			} else if( subviewContainer.y < bottom ){
				subviewContainer.y = (_posYOnMouseDown + gap + bottom )/2 ;
			} else {
				subviewContainer.y = _posYOnMouseDown + gap;
			}
			_mouseMoveProcessed = true;
			//Console.log( "_onMouseMove end" );
		}


		public function _loop( e=null ):void{
			//Console.log( "_loop start" );
			_mouseMoveProcessed = false;
			_speed /= this.decelerationRate;
			if( Math.abs(_speed) < 1 ){
				_speed = 0;
			}
			if( _dragging ){
			} else {
				var bottom:int = getBottom();
				// 領域外でマウスを離した時のための計算
				if( subviewContainer.y > 0 ){
					_speed = subviewContainer.y / 4;
				} else if( subviewContainer.y < bottom ){
					_speed = (subviewContainer.y - bottom) / 4;
				}
				subviewContainer.y -= _speed;
				if( (_speed<0?-_speed:_speed) < 0.2 ){// 高速に絶対値を求める
					_speed = 0;
				}
			}
			if( _speed == 0 && _isScrolling==true && _dragging==false ){
				_isScrolling = false;
				//Console.log( "UIScrollView スクロール終了しました。" );
				subviewContainer.mouseChildren = true;
			}

			// 慣性移動中もイベントを発行するため、mouseMoveではなくenterframeループでイベントを発行
			if( subviewContainer.y > _prevPosY ){
				this.dispatchEvent( new Event("onMoveUp") );
			} else if( subviewContainer.y < _prevPosY ){
				this.dispatchEvent( new Event("onMoveDown") );
			}
			//this.dispatchEvent( new Event("onMoveDown") );
			_prevPosY = subviewContainer.y;
			//Console.log( "_loop end" );

		}


		// 一番下にスクロールしたときのy座標を求める
		private function getBottom():int{
			var bottom:int = this.frame.height - contentSize.height;
			if( bottom > 0 ){
				bottom = 0;
			}
			return bottom;
		}





	}
}